package domain;

import java.sql.Date;

import com.sun.org.apache.bcel.internal.generic.ACONST_NULL;

import util.*;

import java.util.*;

public class User implements Comparable {

	private long uid;
	private String email;
	private String password;
	private String firstName;
	private String lastName;
	private Date dateOfBirth;
	private String imageURL;
	private String summary;
	private String city;
	private String tel;
	private int title;
	private double rating;
	private long popularity;
	private boolean available;
	private boolean real;
	private boolean female;
	private Actor actorFeatures;

	// Lists concerning the movies associated with this user
	private LinkedList<Role> actedMovies;
	private LinkedList<Movie> directedMovies;
	private LinkedList<Movie> worked_as_crewMovies;

	// Constructor of the User object
	public User(long uid, String email, String password, String firstName,
			String lastName, Date dateOfBirth, String imageURL, String summary,
			String city, String tel, int title, double rating, long popularity,
			Actor actorFeatures, boolean isAvailable, boolean isReal,
			boolean isFemale) {
		this.uid = uid;
		this.email = email;
		this.password = password;
		this.firstName = firstName;
		this.lastName = lastName;
		this.imageURL = imageURL;
		this.summary = summary;
		this.title = title;
		this.rating = rating;
		this.popularity = popularity;
		this.dateOfBirth = dateOfBirth;
		this.city = city;
		this.tel = tel;
		this.available = isAvailable;
		this.female = isFemale;
		this.real = isReal;
		this.actorFeatures = actorFeatures;
	}

	// To be used whenever these lists are required
	public void initializeAssociationLists(LinkedList<Role> actedMovies,
			LinkedList<Movie> directedMovies,
			LinkedList<Movie> worked_as_crewMovies) {
		this.actedMovies = actedMovies;
		this.directedMovies = directedMovies;
		this.worked_as_crewMovies = worked_as_crewMovies;
	}

	// Get and set functions of the class variables
	public long getUid() {
		return uid;
	}

	public String getImageURL() {
		if (imageURL.startsWith("jsp/")) {
			return ExpindConstants.rootPath + "/" + imageURL;
		} else
			return imageURL;
	}

	public void setImageURL(String imageURL) {
		this.imageURL = imageURL;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getFirstName() {
		return this.firstName;
	}

	public String getName() {
		return this.firstName + " " + this.lastName;
	}

	public String getSummary() {
		return summary;
	}

	public void setSummary(String summary) {
		this.summary = summary;
	}

	public boolean isAvailable() {
		return available;
	}

	public void setAvailable(boolean available) {
		this.available = available;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getTel() {
		return tel;
	}

	public void setTel(String tel) {
		this.tel = tel;
	}

	public boolean isReal() {
		return real;
	}

	public void setReal(boolean real) {
		this.real = real;
	}

	public boolean isFemale() {
		return female;
	}

	public void setFemale(boolean female) {
		this.female = female;
	}

	public double getRating() {
		return rating;
	}

	public void setRating(double rating) {
		this.rating = rating;
	}

	public long getPopularity() {
		return popularity;
	}

	public void setPopularity(long popularity) {
		this.popularity = popularity;
	}

	public int getTitle() {
		return title;
	}

	public void setTitle(int title) {
		this.title = title;
	}

	public Date getDateOfBirth() {
		return dateOfBirth;
	}

	public void setDateOfBirth(Date dateOfBirth) {
		this.dateOfBirth = dateOfBirth;
	}

	public int getYearOfBirth() {
		if (dateOfBirth != null) {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(dateOfBirth);
			return calendar.get(Calendar.YEAR);
		}
		return 2000;
	}

	public int getMonthOfBirth() {
		if (dateOfBirth != null) {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(dateOfBirth);
			return calendar.get(Calendar.MONTH);
		}
		return 1;
	}

	public int getDayOfBirth() {
		if (dateOfBirth != null) {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(dateOfBirth);
			return calendar.get(Calendar.DAY_OF_MONTH);
		}
		return 1;
	}

	public Actor getActorFeatures() {
		return this.actorFeatures;
	}

	public void setActorFeatures(Actor actorFeatures) {
		this.actorFeatures = actorFeatures;
	}

	public boolean isActor() {
		return (title & TitleUtil.actor_bit) == TitleUtil.actor_bit;
	}

	public boolean isDirector() {
		return (title & TitleUtil.director_bit) == TitleUtil.director_bit;
	}

	public boolean isCameraman() {
		return (title & TitleUtil.cameraman_bit) == TitleUtil.cameraman_bit;
	}

	public boolean isLightingDirector() {
		return (title & TitleUtil.lighting_director_bit) == TitleUtil.lighting_director_bit;
	}

	public boolean isSetDecorator() {
		return (title & TitleUtil.set_decorator_bit) == TitleUtil.set_decorator_bit;
	}

	public boolean isMakeUpArtist() {
		return (title & TitleUtil.make_up_artist_bit) == TitleUtil.make_up_artist_bit;
	}

	public boolean isCostumeDesigner() {
		return (title & TitleUtil.costume_designer_bit) == TitleUtil.costume_designer_bit;
	}

	public boolean isPropsMaster() {
		return (title & TitleUtil.props_master_bit) == TitleUtil.props_master_bit;
	}

	public List<Title> getTitles() {
		List<Title> titles = new ArrayList<Title>();
		List<Title> allTitles = TitleUtil.getTitles();
		for (Title t : allTitles) {
			if ((title & t.getTitleBit()) == t.getTitleBit()) {
				titles.add(t);
			}
		}
		return titles;
	}

	public int getRoundedRate() {
		return RateUtil.getRate(rating);
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == this) {
			return true;
		}
		if (obj == null || obj.getClass() != this.getClass()) {
			return false;
		}

		User user = (User) obj;
		return uid == user.getUid();
	}

	@Override
	public int hashCode() {
		return (int) uid;
	}

	@Override
	public int compareTo(Object obj) {
		User user = (User) obj;
		return (int) (uid - user.getUid());
	}
}